package com.flykoc.lightinggem.api;

import com.flykoc.lightinggem.Entry;
import com.flykoc.lightinggem.dao.GemDao;
import com.flykoc.lightinggem.dto.LightingGem;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 宝石API
 *
 * @author Zoyn
 * @since 2017-10-28
 */
public class GemAPI {

    /**
     * 数字正则
     */
    private static final Pattern SELECT_DOUBLE_NUMBER_REGEX = Pattern.compile("[`~!@#$^&*()=|{}':;,\\[\\]<>/?！￥…（）—【】‘；：”“。，、？%+_]");

    /**
     * 判断一个物品是否是宝石
     *
     * @param itemStack 物品
     * @return true -> 是 / false -> 否
     */
    public static boolean isGem(@Nonnull ItemStack itemStack) {
        boolean flag = false;
        if (itemStack.hasItemMeta()) {
            flag = GemDao.getGems()
                    .stream()
                    .anyMatch(lightingGem -> lightingGem.getItemStack().getItemMeta().equals(itemStack.getItemMeta()));
        }
        return flag;
    }

    /**
     * 取所有宝石的Collection集合
     *
     * @return {@link LightingGem}
     */
    public static Collection<LightingGem> getGems() {
        return GemDao.getGems();
    }

    /**
     * * 通过config内的键名获取LightingGem对象
     *
     * @param keyName 键名
     * @return {@link LightingGem}
     * @throws IllegalArgumentException 当键名获取不到宝石时抛出该异常
     */
    public static LightingGem getGem(String keyName) throws IllegalArgumentException {
        LightingGem gem = GemDao.getGem(keyName);
        if (gem == null) {
            throw new IllegalArgumentException("非法数据异常!无法通过API获取宝石!键名: " + keyName);
        }
        return gem;
    }

    /**
     * 判断一个物品是否是可镶嵌物品
     *
     * @param itemStack 物品
     * @return true -> 是 / false -> 否
     */
    @SuppressWarnings({"deprecation"})
    public static boolean isWeapon(@Nonnull ItemStack itemStack) {
        return Entry.getInstance().weaponIds.contains(itemStack.getTypeId());
    }

    /**
     * 判断一个物品某一行是否拥有指定字符串
     *
     * @param itemStack 物品
     * @param lineTag   字符串
     * @return true -> 是 / false -> 否
     */
    public static boolean hasLore(@Nonnull ItemStack itemStack, @Nonnull String lineTag) {
        boolean flag = false;
        if (itemStack.hasItemMeta()) {
            if (itemStack.getItemMeta().hasLore()) {
                flag = itemStack.getItemMeta().getLore()
                        .stream()
                        .anyMatch(s -> s.contains(lineTag));
            }
        }
        return flag;
    }

    /**
     * 取服务器版本
     *
     * @return 服务器版本字符串
     */
    private static String getServerVersion() {
        return org.bukkit.Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
    }

    /**
     * 反射: 取玩家手中物品
     *
     * @param player 玩家
     * @return 玩家的手中物品的ItemStack对象
     */
    @SuppressWarnings("deprecation")
    public static ItemStack getItemInMainHand(Player player) {
        //判断是否为1.9+
        if (Bukkit.getBukkitVersion().split("-")[0].startsWith("1.9")) {
            try {
                //获取obc下的CraftInventoryPlayer
                Class<?> craftinventory = Class.forName("org.bukkit.craftbukkit." + getServerVersion() + ".inventory.CraftInventoryPlayer");
                //调用其方法getItemInMainHand
                return (ItemStack) craftinventory.getMethod("getItemInMainHand").invoke(player.getInventory());
            } catch (Exception e) {
                System.out.println("错误: " + e.getMessage());
                e.printStackTrace();
            }
        }
        return player.getItemInHand();
    }

    /**
     * 获取物品闪电附加的几率
     *
     * @param itemStack 物品
     * @return 几率[0-100]
     */
    public static double getItemLightingOdds(@Nonnull ItemStack itemStack) {
        double odds = -1;
        if (itemStack.hasItemMeta()) {
            if (itemStack.getItemMeta().hasLore()) {
                Optional<String> tag = itemStack.getItemMeta().getLore()
                        .stream()
                        .filter(s -> s.contains("闪电附加")).findFirst();

                // 有值时
                if (tag.isPresent()) {
                    // 利用正则去除多余符号
                    String num = tag.get().split("\\+")[1];
                    Matcher matcher = SELECT_DOUBLE_NUMBER_REGEX.matcher(num);
                    num = matcher.replaceAll("").trim();
                    odds = Double.parseDouble(num);
                }
            }
        }
        return odds;
    }
}
